#include "Normalizer.h"

void Normalizer::normalizeByMinMax(std::vector<vector<double> >& dataset, bool isTrainSet)
{
	int n = dataset.at(0).size();
		if (isTrainSet){
			max = new double[n-2];
			min = new double[n-2];
			for (int i = 2; i < n; i++){
				max[i-2] = dataset.at(0).at(i);
				min[i-2] = dataset.at(0).at(i);
			}
			
			for (int i = 1; i < dataset.size(); i++){
				for (int j = 2; j < n; j++){
					if (dataset.at(i).at(j) > max[j-2])
						max[j-2] = dataset.at(i).at(j);
					if (dataset.at(i).at(j) < min[j-2])
						min[j-2] = dataset.at(i).at(j);							
				}
			}
		}
		
		for (int i = 0; i < dataset.size(); i++){
			//vector<double> tuple = dataset.at(i);
			for (int j = 2; j < n; j++){
				dataset[i][j] = (dataset[i][j] - min[j-2])/(max[j-2] - min[j-2]);
			}
			//dataset.set(i, tuple);
			
		}
}

void Normalizer::normalizeByZScore(std::vector<vector<double> >& dataset, bool isTrainSet)
{
	int n = dataset.at(0).size();
	if (isTrainSet){
		mean = new double[n-2];
		standardD = new double[n-2];
		for(int j = 0;j < n;j++ )
		{
			mean[j-2] = 0;
			standardD[j-2] = 0;
		}
		
		for (int i = 0; i < dataset.size(); i++){
			for (int j = 2; j < n; j++){
				mean[j-2] += dataset.at(i).at(j);						
			}
		}
		
		for (int i = 2; i < n; i++){
			mean[i-2] /= dataset.size();
			//cout << mean[i-2] << " ";
		}
		//cout << endl;
		


		for (int i = 0; i < dataset.size(); i++){
			for (int j = 2; j < n; j++){
				standardD[j-2] += pow(dataset.at(i).at(j) - mean[j-2], 2);						
			}
		}
		
		for (int i = 2; i < n; i++){
			standardD[i-2] /= dataset.size();
			standardD[i-2] = sqrt(standardD[i-2]);
		}
	}
	
	for (int i = 0; i < dataset.size(); i++){
		//vector<double> tuple = dataset.at(i);
		//cout << tuple.at(2) << "{}" ;

		for (int j = 2; j < n; j++){
			//cout << dataset[i][j] << "-" << mean[j-2] << standardD[j-2] ;
			dataset[i][j] = (dataset[i][j] - mean[j-2]) / standardD[j-2];	
			//cout << dataset[i][j] << endl;
		}

		//cout <<tuple.at(2) <<"{}"<< dataset.at(i).at(2) << endl;
		//dataset[i] = tuple;
	}
}

void Normalizer::normalizeByLogistic(std::vector<vector<double> >& dataset, bool isTrainSet)
{
	int n = dataset.at(0).size();
	for (int i = 0; i < dataset.size(); i++){
	//	System.out.println(i);
		//vector<double> tuple = dataset.at(i);
		for (int j = 2; j < n; j++){
			double temp = 1 + pow(E,0 -dataset[i][j]);
			dataset[i][j] = (double)1 / temp;

		}
	}
}